package neptune.web.server.services.user;

import it.robertobifulco.ias.IncorrectParamsException;
import it.robertobifulco.ias.UnauthorizedOperationException;
import it.robertobifulco.ias.rolemanager.RoleUndefinedException;
import javax.servlet.http.HttpSession;
import neptune.web.client.model.SerializableUser;
import neptune.web.client.services.SecurityException;
import neptune.web.client.services.user.UserService;
import neptune.web.server.model.ApplicationUser;
import neptune.web.server.operations.AddUser;
import neptune.web.server.operations.GetUser;
import neptune.web.server.operations.GetUsers;
import neptune.web.server.operations.RemoveUser;
import neptune.web.server.operations.UpdateUser;
import neptune.web.server.security.IASCreationException;
import neptune.web.server.security.SecurityHelper;
import neptune.web.server.services.SerializationHelper;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * 
 * @author Roberto Bifulco [info@RobertoBifulco.it] [RobertoBifulco.it]
 * @author Luigi Lorenzo Arpino [luigiarpino@yahoo.it]
 * 
 */
public class UserServiceImpl extends RemoteServiceServlet implements
		UserService {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public boolean addUser(SerializableUser user) throws SecurityException,
			Exception 
	{
		String userName = user.getUsername();
		if ( ! isValidUserName(userName))
		{
			String msg="\n The username contains invalids chars!";
			throw new SecurityException(msg);
		}
		try {
			// Recupera la sessione utente e l'operazione
			HttpSession session = getThreadLocalRequest().getSession(false);
			AddUser operation = (AddUser) SecurityHelper.getOperation(
					AddUser.ID, session);

			ApplicationUser appUsr = SerializationHelper
					.toApplicationUser(user);

			operation.execute(new Object[] { appUsr });
			
			return true;
		} catch (UnauthorizedOperationException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (RoleUndefinedException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (IncorrectParamsException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		}
	}

	public boolean removeUser(String username) throws SecurityException,
			Exception 
	{

		try 
		{
			HttpSession session = getThreadLocalRequest().getSession(false);
			RemoveUser operation = (RemoveUser) SecurityHelper.getOperation(
					RemoveUser.ID, session);

			Boolean isRemoved = (Boolean)operation.execute(new Object[] { username })[0];
			
			return isRemoved;
			
		} catch (UnauthorizedOperationException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (RoleUndefinedException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (IncorrectParamsException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		}
	}

	public SerializableUser[] getUsers(int begin, int end, int sortId,
			boolean ascending) throws SecurityException, Exception {

		try {
			HttpSession session = getThreadLocalRequest().getSession(false);
			GetUsers operation = (GetUsers) SecurityHelper.getOperation(
					GetUsers.ID, session);

			ApplicationUser[] users = (ApplicationUser[]) operation
					.execute(new Object[] { new Integer(begin),
							new Integer(end), new Integer(sortId),
							new Boolean(ascending) });

			SerializableUser[] returnValue = SerializationHelper
					.toSerializableUser(users);

			return returnValue;
		} catch (IASCreationException e) {
			e.printStackTrace();
		} catch (UnauthorizedOperationException e) {
			throw new SecurityException(e.getMessage());
		} catch (RoleUndefinedException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (IncorrectParamsException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		}

		return null;
	}

	public SerializableUser getUser(String username) throws SecurityException,
			Exception {
		try {
			// Recupera la sessione utente e l'operazione
			HttpSession session = getThreadLocalRequest().getSession(false);
			GetUser operation = (GetUser) SecurityHelper.getOperation(
					GetUser.ID, session);

			ApplicationUser usr = (ApplicationUser) (operation
					.execute(new Object[] { username }))[0];

			return SerializationHelper.toSerializableUser(usr);
		} catch (UnauthorizedOperationException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (RoleUndefinedException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (IncorrectParamsException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		}
	}

	public boolean updateUser(SerializableUser user) throws SecurityException,
			Exception {
		try {
			// Recupera la sessione utente e l'operazione
			HttpSession session = getThreadLocalRequest().getSession(false);
			UpdateUser operation = (UpdateUser) SecurityHelper.getOperation(
					UpdateUser.ID, session);

			ApplicationUser appUsr = SerializationHelper
					.toApplicationUser(user);

			operation.execute(new Object[] { appUsr });
			
			return true;

		} catch (UnauthorizedOperationException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (RoleUndefinedException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (IncorrectParamsException e) {
			e.printStackTrace();
			throw new SecurityException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());
		}
	}
	
	/**
	 * Verifica la correttezza dell'username 
	 * 
	 * @param userName
	 * @return
	 */
	private boolean isValidUserName(String userName)
	{
		/*
		 *  Codici ASCII
		 	A=65
			Z=90
			a=97
			z=122
			0=48
			9=57
			_=95
		 */
		boolean isValid=true;
		byte[] bytes=userName.getBytes();
		for (int i=0; i<bytes.length ; i++)
		{
			byte b=bytes[i];
			//System.out.println(expName.charAt(i)+"="+b);
			if( (b>=65 && b<=90) || (b>=97 && b<=122) || (b>=48 && b<=57) || (b==95) )
			{
				//  il carattere è OK
			}
			else
			{
				//  il carattere non è ammesso
				isValid=false;
			}
		}
		return isValid;
	}
}
